/*!
* $.dialog 5 plugins
* Date: 2012-03-16
* https://github.com/aui/artDialog
* (c) 2009-2012 TangBin, http://www.planeArt.cn
*
* This is licensed under the GNU LGPL, version 2.1 or later.
* For details, see: http://creativecommons.org/licenses/LGPL/2.1/
*/

;(function ($, window,  undefined) {
	var _topDialog, _proxyDialog, _zIndex,
	_data = '@ARTDIALOG.DATA',
	_open = '@ARTDIALOG.OPEN',
	_opener = '@ARTDIALOG.OPENER',
	_winName = window.name = window.name	|| '@ARTDIALOG.WINNAME' + + new Date,
	_isIE6 = window.VBArray && !window.XMLHttpRequest;
	$(function () {
		!window.jQuery && document.compatMode === 'BackCompat'
		// 不支持怪异模式，请用主流的XHTML1.0或者HTML5的DOCTYPE申明
		&& alert('artDialog Error: document.compatMode === "BackCompat"');
	});
	/** 获取 artDialog 可跨级调用的最高层的 window 对象 */
	var _top = $.dialog.top = function () {
		var top = window,
		test = function (name) {
			try {
				var doc = window[name].document;	// 跨域|无权限
				doc.getElementsByTagName; 			// chrome 本地安全限制
			} catch (e) {
				return false;
			};
			
			return window[name].$.dialog
			// 框架集无法显示第三方元素
			&& doc.getElementsByTagName('frameset').length === 0;
		};
		
		if (test('top')) {
			top = window.top;
		} else if (test('parent')) {
			top = window.parent;
		};
		
		return top;
	}();
	$.dialog.parent = _top; // 兼容v4.1之前版本，未来版本将删除此
	_topDialog = _top.$.dialog;
	/**
	 * 跨框架数据共享接口
	 * @see		http://www.planeart.cn/?p=1554
	 * @param	{String}	存储的数据名
	 * @param	{Any}		将要存储的任意数据(无此项则返回被查询的数据)
	 */
	$.dialog.data = function (name, value) {
		var top = $.dialog.top,
			cache = top[_data] || {};
		top[_data] = cache;
		
		if (value !== undefined) {
			cache[name] = value;
		} else {
			return cache[name];
		};
		return cache;
	};
	
	/**
	 * 数据共享删除接口
	 * @param	{String}	删除的数据名
	 */
	$.dialog.removeData = function (name) {
		var cache = $.dialog.top[_data];
		if (cache && cache[name]) delete cache[name];
	};
	/** 跨框架普通对话框 */
	$.dialog.through = _proxyDialog = function () {
		var api = _topDialog.apply(this, arguments);
			
		// 缓存从当前 window（可能为iframe）调出所有跨框架对话框，
		// 以便让当前 window 卸载前去关闭这些对话框。
		// 因为iframe注销后也会从内存中删除其创建的对象，这样可以防止回调函数报错
		if (_top !== window) $.dialog.list[api.config.id] = api;
		return api;
	};

	// 框架页面卸载前关闭所有穿越的对话框
	_top !== window && $(window).bind('unload', function () {
		var list = $.dialog.list, config;
		for (var i in list) {
			if (list[i]) {
				config = list[i].config;
				if (config) config.duration = 0; // 取消动画
				list[i].close();
				//delete list[i];
			};
		};
	});
	/**
	 * 弹窗 (iframe)
	 * @param	{String}	地址
	 * @param	{Object}	配置参数. 这里传入的回调函数接收的第1个参数为iframe内部window对象
	 * @param	{Boolean}	是否允许缓存. 默认true
	 */
	$.dialog.open = function (url, options, cache) {
		options = options || {};
		
		var api, dom,
			$content, $main, iframe, $iframe, $idoc, iwin, ibody,
			top = $.dialog.top,
			initCss = 'position:absolute;left:-9999em;top:-9999em;border:none 0;background:transparent',
			loadCss = 'width:100%;height:100%;border:none 0';
			
		if (cache === false) {
			var ts = + new Date,
				ret = url.replace(/([?&])_=[^&]*/, "$1_=" + ts );
			url = ret + ((ret === url) ? (/\?/.test(url) ? "&" : "?") + "_=" + ts : "");
		};
			
		var load = function () {
			var iWidth, iHeight,
				loading = dom.content.find('.d-loading'),
				aConfig = api.config;
				
			$content.addClass('d-state-full');
			
			loading && loading.hide();
			
			try {
				iwin = iframe.contentWindow;
				$idoc = $(iwin.document);
				ibody = iwin.document.body;
			} catch (e) {// 跨域
				iframe.style.cssText = loadCss;
				
				aConfig.follow
				? api.follow(aConfig.follow)
				: api.position(aConfig.left, aConfig.top);
				
				options.initialize && options.initialize.call(api, iwin, top);
				options.initialize = null;
				return;
			};
			
			// 获取iframe内部尺寸
			iWidth = aConfig.width === 'auto'
			? $idoc.width() + (_isIE6 ? 0 : parseInt($(ibody).css('marginLeft')))
			: aConfig.width;
			
			iHeight = aConfig.height === 'auto'
			? $idoc.height()
			: aConfig.height;
			
			// 适应iframe尺寸
			setTimeout(function () {
				iframe.style.cssText = loadCss;
			}, 0);// setTimeout: 防止IE6~7对话框样式渲染异常
			api.size(iWidth, iHeight);
			
			// 调整对话框位置
			aConfig.follow
			? api.follow(aConfig.follow)
			: api.position(aConfig.left, aConfig.top);
			
			options.initialize && options.initialize.call(api, iwin, top);
			options.initialize = null;
		};
			
		var config = {
			initialize: function () {
				api = this;
				dom = api.dom;
				$main = dom.main;
				$content = dom.content;
				
				iframe = api.iframe = top.document.createElement('iframe');
				iframe.src = url;
				iframe.name = 'Open' + api.config.id;
				iframe.style.cssText = initCss;
				iframe.setAttribute('frameborder', 0, 0);
				iframe.setAttribute('allowTransparency', true);
				
				$iframe = $(iframe);
				
				dom.content[0].appendChild(iframe);
				iwin = iframe.contentWindow;
				
				try {
					iwin.name = iframe.name;
					$.dialog.data(iframe.name + _open, api);
					$.dialog.data(iframe.name + _opener, window);
				} catch (e) {};
				
				$iframe.bind('load', load);
			},
			close: function () {
				$iframe.css('display', 'none').unbind('load', load);
				
				if (options.close && options.close.call(this, iframe.contentWindow, top) === false) {
					return false;
				};
				$content.removeClass('d-state-full');
				
				// 重要！需要重置iframe地址，否则下次出现的对话框在IE6、7无法聚焦input
				// IE删除iframe后，iframe仍然会留在内存中出现上述问题，置换src是最容易解决的方法
				$iframe[0].src = 'about:blank';
				$iframe.remove();
				
				try {
					$.dialog.removeData(iframe.name + _open);
					$.dialog.removeData(iframe.name + _opener);
				} catch (e) {};
			}
		};
		
		// 回调函数第一个参数指向iframe内部window对象
		if (typeof options.ok === 'function') config.ok = function () {
			return options.ok.call(api, iframe.contentWindow, top);
		};
		if (typeof options.cancel === 'function') config.cancel = function () {
			return options.cancel.call(api, iframe.contentWindow, top);
		};
		
		delete options.content;

		for (var i in options) {
			if (config[i] === undefined) config[i] = options[i];
		};
		
		return _proxyDialog(config);
	};


	/** 引用open方法扩展方法(在open打开的iframe内部私有方法) */
	$.dialog.open.api = $.dialog.data(_winName + _open);


	/** 引用open方法触发来源页面window(在open打开的iframe内部私有方法) */
	$.dialog.opener = $.dialog.data(_winName + _opener) || window;
	$.dialog.open.origin = $.dialog.opener; // 兼容v4.1之前版本，未来版本将删除此

	/** $.dialog.open 打开的iframe页面里关闭对话框快捷方法 */
	$.dialog.close = function () {
		var api = $.dialog.data(_winName + _open);
		api && api.close();
		return false;
	};

	// 点击iframe内容切换叠加高度
	_top != window && $(document).bind('mousedown', function () {
		var api = $.dialog.open.api;
		//api && api.zIndex();
	});
	/**
	 * Ajax填充内容
	 * @param	{String}			地址
	 * @param	{Object}			配置参数
	 * @param	{Boolean}			是否允许缓存. 默认true
	 */
	$.dialog.load = function(url, options, cache){
		cache = cache || false;
		var opt = options || {};
			
		var config = {
			initialize: function(here){
				var api = this,
					aConfig = api.config;
				$.ajax({
					url: url,
					success: function (content) {
						api.content(content);
						opt.initialize && opt.initialize.call(api, here);		
					},
					cache: cache
				});
				
			}
		};
		
		delete options.content;
		
		for (var i in opt) {
			if (config[i] === undefined) config[i] = opt[i];
		};
		
		return _proxyDialog(config);
	};
		
	$.dialog.load2 = function (url, options, cache) {
		$.dialog({
	        id: 'Dialog-load-start',
	        fixed: true
	    });
		$.ajax({
			url: url,
			success: function (c) {
				$.dialog.get('Dialog-load-start').close();
				$.dialog({
			        id: 'Dialog-load',
			        content:c,
			        fixed: true,
			        ok: true
			    });
			},
			cache: cache
		});
		return true;
	};
	/**
	 * 短暂提示
	 * @param	{String}	提示内容
	 * @param	{Number}	显示时间 (默认1.5秒)
	 */
	$.dialog.tips = function (content, time) {
		/*return _proxyDialog({
			id: 'Tips',
			title: false,
			cancel: false,
			fixed: true,
			lock: false
		})
		.content('<div style="padding: 0 1em;">' + content + '</div>')
		.time(time || 1.5);
	*/
	return $.dialog({
        id: 'Tips',
        title: false,
        cancel: false,
        fixed: true,
        lock: false,
        content: '<div style="padding: 0 1em;">' + content + '</div>',
        time:((time||1.5)*1000)
    });
	};
/**
 * 警告
 * @param   {String, HTMLElement}   消息内容
 * @param   {Function}              (可选) 回调函数
 */
$.alert = $.dialog.alert = function (content, callback) {
    return $.dialog({
        id: 'Alert',
        fixed: true,
        lock: true,
        content: content,
        ok: true,
        beforeunload: callback
    });
};


/**
 * 确认选择
 * @param   {String, HTMLElement}   消息内容
 * @param   {Function}              确定按钮回调函数
 * @param   {Function}              取消按钮回调函数
 */
$.confirm = $.dialog.confirm = function (content, ok, cancel) {
    return $.dialog({
        id: 'Confirm',
        fixed: true,
        lock: true,
        content: content,
        ok: ok,
        cancel: cancel
    });
};


/**
 * 输入框
 * @param   {String, HTMLElement}   消息内容
 * @param   {Function}              确定按钮回调函数。函数第一个参数接收用户录入的数据
 * @param   {String}                输入框默认文本
 */
$.prompt = $.dialog.prompt = function (content, ok, defaultValue) {
    defaultValue = defaultValue || '';
    var input;
    
    return $.dialog({
        id: 'Prompt',
        fixed: true,
        lock: true,
        content: [
            '<div style="margin-bottom:5px;font-size:12px">',
                content,
            '</div>',
            '<div>',
                '<input type="text" class="d-input-text" value="',
                    defaultValue,
                '" style="width:18em;padding:6px 4px" />',
            '</div>'
            ].join(''),
        initialize: function () {
            input = this.dom.content.find('.d-input-text')[0];
            input.select();
            input.focus();
        },
        ok: function () {
            return ok && ok.call(this, input.value);
        },
        cancel: function () {}
    });
};


/** 抖动效果 */
$.dialog.prototype.shake = (function () {

    var fx = function (ontween, onend, duration) {
        var startTime = + new Date;
        var timer = setInterval(function () {
            var runTime = + new Date - startTime;
            var pre = runTime / duration;
                
            if (pre >= 1) {
                clearInterval(timer);
                onend(pre);
            } else {
                ontween(pre);
            };
        }, 13);
    };
    
    var animate = function (elem, distance, duration) {
        var quantity = arguments[3];

        if (quantity === undefined) {
            quantity = 6;
            duration = duration / quantity;
        };
        
        var style = elem.style;
        var from = parseInt(style.marginLeft) || 0;
        
        fx(function (pre) {
            elem.style.marginLeft = from + (distance - from) * pre + 'px';
        }, function () {
            if (quantity !== 0) {
                animate(
                    elem,
                    quantity === 1 ? 0 : (distance / quantity - distance) * 1.3,
                    duration,
                    -- quantity
                );
            };
        }, duration);
    };
    
    return function () {
        animate(this.dom.wrap[0], 40, 600);
        return this;
    };
})();


// 拖拽支持
var DragEvent = function () {
    var that = this,
        proxy = function (name) {
            var fn = that[name];
            that[name] = function () {
                return fn.apply(that, arguments);
            };
        };
        
    proxy('start');
    proxy('over');
    proxy('end');
};


DragEvent.prototype = {

    // 开始拖拽
    // onstart: function () {},
    start: function (event) {
        $(document)
        .bind('mousemove', this.over)
        .bind('mouseup', this.end);
            
        this._sClientX = event.clientX;
        this._sClientY = event.clientY;
        this.onstart(event.clientX, event.clientY);

        return false;
    },
    
    // 正在拖拽
    // onover: function () {},
    over: function (event) {		
        this._mClientX = event.clientX;
        this._mClientY = event.clientY;
        this.onover(
            event.clientX - this._sClientX,
            event.clientY - this._sClientY
        );
        
        return false;
    },
    
    // 结束拖拽
    // onend: function () {},
    end: function (event) {
        $(document)
        .unbind('mousemove', this.over)
        .unbind('mouseup', this.end);
        
        this.onend(event.clientX, event.clientY);
        return false;
    }
    
};

var $window = $(window),
    $document = $(document),
    html = document.documentElement,
    isIE6 = !('minWidth' in html.style),
    isLosecapture = !isIE6 && 'onlosecapture' in html,
    isSetCapture = 'setCapture' in html,
    dragstart = function () {
        return false
    };
    
var dragInit = function (event) {
    
    var dragEvent = new DragEvent,
        api = $.dialog.focus,
        dom = api.dom,
        $wrap = dom.wrap,
        $title = dom.title,
        $main = dom.main,
        wrap = $wrap[0],
        title = $title[0],
        main = $main[0],
        wrapStyle = wrap.style,
        mainStyle = main.style;
        
        
    var isResize = event.target === dom.se[0] ? true : false;
    var isFixed = wrap.style.position === 'fixed',
        minX = isFixed ? 0 : $document.scrollLeft(),
        minY = isFixed ? 0 : $document.scrollTop(),
        maxX = $window.width() - wrap.offsetWidth + minX,
        maxY = $window.height() - wrap.offsetHeight + minY;
    
    
    var startWidth, startHeight, startLeft, startTop;
    
    
    // 对话框准备拖动
    dragEvent.onstart = function (x, y) {
    
        if (isResize) {
            startWidth = main.offsetWidth;
            startHeight = main.offsetHeight;
        } else {
            startLeft = wrap.offsetLeft;
            startTop = wrap.offsetTop;
        };
        
        $document.bind('dblclick', dragEvent.end)
        .bind('dragstart', dragstart);
            
        if (isLosecapture) {
            $title.bind('losecapture', dragEvent.end)
        } else {
            $window.bind('blur', dragEvent.end)
        };
            
        isSetCapture && title.setCapture();
        
        $wrap.addClass('d-state-drag');
        api.focus();
    };
    
    // 对话框拖动进行中
    dragEvent.onover = function (x, y) {
    
        if (isResize) {
            var width = x + startWidth,
                height = y + startHeight;
            
            wrapStyle.width = 'auto';
            mainStyle.width = Math.max(0, width) + 'px';
            wrapStyle.width = wrap.offsetWidth + 'px';
            
            mainStyle.height = Math.max(0, height) + 'px';
            
        } else {
            var left = Math.max(minX, Math.min(maxX, x + startLeft)),
                top = Math.max(minY, Math.min(maxY, y + startTop));

            wrapStyle.left = left  + 'px';
            wrapStyle.top = top + 'px';
        };
        
        
    };
    
    // 对话框拖动结束
    dragEvent.onend = function (x, y) {
    
        $document.unbind('dblclick', dragEvent.end)
        .unbind('dragstart', dragstart);
        
        if (isLosecapture) {
            $title.unbind('losecapture', dragEvent.end);
        } else {
            $window.unbind('blur', dragEvent.end)
        };
        
        isSetCapture && title.releaseCapture();
        
        $wrap.removeClass('d-state-drag');
    };
    
    
    dragEvent.start(event);
    
};


// 代理 mousedown 事件触发对话框拖动
$(document).bind('mousedown', function (event) {
    var api = $.dialog.focus;
    if (!api) return;

    var target = event.target,
        config = api.config,
        dom = api.dom;
    
    if (config.drag !== false && target === dom.title[0]
    || config.resize !== false && target === dom.se[0]) {
        dragInit(event);
        
        // 防止firefox与chrome滚屏
        return false;
    };
});


}(this.art || this.jQuery,this));

